package com.zenchn.service.impl;

import com.zenchn.dao.TMiCustomerMapper;
import com.zenchn.dynamic.TMiCustomerDynamicMapper;
import com.zenchn.entity.ReportStatisticsVO;
import com.zenchn.enums.CustomerTypeEnum;
import com.zenchn.generic.GenericDao;
import com.zenchn.generic.GenericServiceImpl;
import com.zenchn.model.TMiCustomer;
import com.zenchn.model.TMiCustomerExample;
import com.zenchn.service.CustomerService;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
import org.mybatis.dynamic.sql.select.SelectModel;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

import static com.zenchn.dynamic.TMiCustomerDynamicSqlSupport.*;
import static org.mybatis.dynamic.sql.SqlBuilder.*;

/**
 * @author wlf
 * @version 1.0
 * @date 2021/6/7 11:54:23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CustomerServiceImpl extends GenericServiceImpl<TMiCustomer, String, TMiCustomerExample> implements CustomerService {

    @Resource
    private TMiCustomerMapper mapper;

    @Resource
    private TMiCustomerDynamicMapper dynamicMapper;

    @Override
    public GenericDao<TMiCustomer, String, TMiCustomerExample> getDao() {
        return mapper;
    }

    @Override
    public boolean checkExistCustomer(String customerName) {
        TMiCustomerExample example = new TMiCustomerExample();
        example.createCriteria().andCustomerNameEqualTo(customerName);
        List<TMiCustomer> tMiCustomers = mapper.selectByExample(example);
        return tMiCustomers == null || tMiCustomers.isEmpty();
    }

    @Override
    public List<TMiCustomer> selectAgentDynamicSqlByParameter(String keyword, List<String> areasCodeList, String areasCode, String accountId, Integer level, LocalDateTime startDate, LocalDateTime endDate) {
        QueryExpressionDSL<SelectModel> dsl = select(TMiCustomer.allColumns()).from(TMiCustomer);

        QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder dslWhere = dsl.where(TMiCustomer.customerType, isEqualTo(CustomerTypeEnum.AGENT.getType()));

        if (null != areasCodeList && !areasCodeList.isEmpty()) {
            dslWhere.and(TMiCustomer.areasCode, isIn(areasCodeList));
        }

        if (null != areasCode && !"".equals(areasCode.trim())) {
            dslWhere.and(TMiCustomer.areasCode, isEqualTo(areasCode));
        }

        if (null != accountId && !"".equals(accountId.trim())) {
            dslWhere.and(TMiCustomer.accountId, isEqualTo(accountId));
        }

        if (null != level) {
            dslWhere.and(TMiCustomer.level, isEqualTo(level));
        }

        if (null != startDate) {
            dslWhere.and(TMiCustomer.createTime, isGreaterThanOrEqualTo(startDate));
        }

        if (null != endDate) {
            dslWhere.and(TMiCustomer.createTime, isLessThanOrEqualTo(endDate));
        }

        if (null != keyword && !"".equals(keyword.trim())) {
            keyword = "%" + keyword.trim() + "%";
            dslWhere.and(TMiCustomer.customerName, isLike(keyword));
        }

        SelectStatementProvider selectStatement = dsl.orderBy(TMiCustomer.createTime.descending()).build().render(RenderingStrategies.MYBATIS3);

        return dynamicMapper.selectMany(selectStatement);
    }

    @Override
    public List<TMiCustomer> selectHospitalDynamicSqlByParameter(String keyword, List<String> areasCodeList, String areasCode, String accountId, Integer level, LocalDateTime startDate, LocalDateTime endDate) {
        QueryExpressionDSL<SelectModel> dsl = select(TMiCustomer.allColumns()).from(TMiCustomer);

        QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder dslWhere = dsl.where(TMiCustomer.customerType, isEqualTo(CustomerTypeEnum.HOSPITAL.getType()));

        if (null != areasCodeList && !areasCodeList.isEmpty()) {
            dslWhere.and(TMiCustomer.areasCode, isIn(areasCodeList));
        }

        if (null != areasCode && !"".equals(areasCode.trim())) {
            dslWhere.and(TMiCustomer.areasCode, isEqualTo(areasCode));
        }

        if (null != accountId && !"".equals(accountId.trim())) {
            dslWhere.and(TMiCustomer.accountId, isEqualTo(accountId));
        }

        if (null != level) {
            dslWhere.and(TMiCustomer.level, isEqualTo(level));
        }

        if (null != startDate) {
            dslWhere.and(TMiCustomer.createTime, isGreaterThanOrEqualTo(startDate));
        }

        if (null != endDate) {
            dslWhere.and(TMiCustomer.createTime, isLessThanOrEqualTo(endDate));
        }

        if (null != keyword && !"".equals(keyword.trim())) {
            keyword = "%" + keyword.trim() + "%";
            dslWhere.and(TMiCustomer.customerName, isLike(keyword));
        }

        SelectStatementProvider selectStatement = dsl.orderBy(TMiCustomer.createTime.descending()).build().render(RenderingStrategies.MYBATIS3);

        return dynamicMapper.selectMany(selectStatement);
    }

    @Override
    public List<ReportStatisticsVO> selectCurCustomerNum(List<String> areasCodeList, String areasCode, String accountId, String customerType, LocalDateTime startDate, LocalDateTime endDate) {
        return mapper.selectCurCustomerNum(areasCodeList, areasCode, accountId, customerType, startDate, endDate);
    }

    @Override
    public List<ReportStatisticsVO> selectFinalCustomerAllNum(List<String> areasCodeList, String areasCode, String accountId, String customerType, LocalDateTime endDate) {
        return mapper.selectFinalCustomerAllNum(areasCodeList, areasCode, accountId, customerType, endDate);
    }

    @Override
    public List<ReportStatisticsVO> selectFinalCustomerLevelNum(List<String> areasCodeList, String areasCode, String accountId, String customerType, LocalDateTime endDate) {
        return mapper.selectFinalCustomerLevelNum(areasCodeList, areasCode, accountId, customerType, endDate);
    }

    @Override
    public List<ReportStatisticsVO> selectNewCustomerLevelNum(List<String> areasCodeList, String areasCode, String accountId, String customerType) {
        return mapper.selectNewCustomerLevelNum(areasCodeList, areasCode, accountId, customerType);
    }

    @Override
    public List<ReportStatisticsVO> selectCurCustomerUpgradeNum(List<String> areasCodeList, String areasCode, String accountId, String customerType, LocalDateTime startDate, LocalDateTime endDate) {
        return mapper.selectCurCustomerUpgradeNum(areasCodeList, areasCode, accountId, customerType, startDate, endDate);
    }

    @Override
    public List<ReportStatisticsVO> selectCurCustomerFinishNum(List<String> areasCodeList, String areasCode, String accountId, String customerType, LocalDateTime startDate, LocalDateTime endDate) {
        return mapper.selectCurCustomerFinishNum(areasCodeList, areasCode, accountId, customerType, startDate, endDate);
    }
}
